﻿using System;
using System.Linq;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Chenglin.W8Timer
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : LayoutAwarePage
    {
        private Frame _hiddenFrame = null;
        private string _currentScenario;

        public MainPage()
        {
            this.InitializeComponent();

            // This frame is hidden, meaning it is never shown. It is simply used to load
            // each scenario page and then pluck out the sections and place them into
            // the UserControls on the main page.
            _hiddenFrame = new Windows.UI.Xaml.Controls.Frame();
            _hiddenFrame.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            ContentRoot.Children.Add(_hiddenFrame);

            this.SizeChanged += WindowSizeChanged;
        }

        private void WindowSizeChanged(object sender, SizeChangedEventArgs e)
        {
            VisualStateManager.GoToState(ScenarioSection, DetermineVisualState(ApplicationView.Value), false);
        }

        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            bool loaded = false;
            object mode;
            if (SuspensionManager.SessionState.TryGetValue(Constants.KeyScenario, out mode))
            {
                try
                {
                    LoadScenario(Constants.Scenarios[(string)mode]);
                    loaded = true;
                }
                catch (Exception)
                {
                    // Failed to load the scenario which was loaded before.
                    // We'll just ignore the exception, and continue to load the default one.
                }
            }

            if (!loaded)
            {
                LoadScenario(Constants.Scenarios.First().Value);
            }
        }

        private void LoadScenario(Scenario scenario)
        {
            if (0 == string.Compare(_currentScenario, scenario.Key, StringComparison.OrdinalIgnoreCase))
            {
                // No need to reload the current scenario.
                return;
            }

            // Load the xaml file of the scenario into the frame
            _hiddenFrame.Navigate(scenario.ClassType, this);

            // Get the top element, the Page, so we can loop up the elements
            // that represent the sections of the xaml file.
            Page hiddenPage = (Page)_hiddenFrame.Content;

            // Get the ScenarioContent element
            UIElement elm = (UIElement)hiddenPage.FindName("ScenarioContent");
            if (elm == null)
            {
                throw new InvalidOperationException("The LayoutRoot element is missing...");
            }

            // Find the PageRoot which parents LayoutRoot in the scenario page
            Panel panel = (Panel)hiddenPage.FindName("LayoutRoot");
            if (panel == null)
            {
                throw new InvalidOperationException("The LayoutRoot element is missing...");
            }

            // Get rid of the content that is currently in 
            panel.Children.Remove(elm);
            ScenarioSection.Content = elm;

            // Save the state
            SuspensionManager.SessionState[Constants.KeyScenario] = scenario.Key;
            _currentScenario = scenario.Key;

            this.InvalidateVisualState();
            VisualStateManager.GoToState(ScenarioSection, DetermineVisualState(ApplicationView.Value), false);
        }

        private void OnTimerModeClick(object sender, RoutedEventArgs e)
        {
            var scenario = Constants.Scenarios[Constants.TimerScenario];
            LoadScenario(scenario);
        }

        private void OnCountDownModeClick(object sender, RoutedEventArgs e)
        {
            var scenario = Constants.Scenarios[Constants.CountDownScenario];
            LoadScenario(scenario);
        }
    }
}
